iT邦幫忙

2022 iThome 鐵人賽

DAY 27
1

最近公司專案有用到「Airflow」來去做排程的處理,剛好跟我們今天要介紹的模式一樣,當我們有一個需求是希望一個工作結束後,會去呼叫另一個工作去執行,像這樣一個呼叫一個,這時候就很適合用 Chain of Responsibility 模式,話不囉嗦,我們直接來看範例!

Chain of Responsibility - 定義

避免請求發送者與接收者耦合在一起,讓多個對象都有可能接收請求,將這些對象連接成一條鏈,並且沿著這條鏈傳遞請求,直到有對象處理它為止。

https://ithelp.ithome.com.tw/upload/images/20221002/20136443OayJAr2L8J.png

(圖片來源:https://media.geeksforgeeks.org/wp-content/uploads/desigmpatternuml1.png)

範例 UML

https://ithelp.ithome.com.tw/upload/images/20221002/20136443kovQhNeF9G.png

Code要點

  • TaskHandler是一個抽象類別,當建構時會傳入下一個需要被呼叫的 Task,HandleTask()是屆時繼承自TaskHandler的實體需要去覆寫的方法,而ExecuteTask()則是去啟動工作,裡面會先去執行實體覆寫的HandleTask(),再去判斷說如果在建構時有傳入下一個需要被呼叫的 Task,那就再去執行他的ExecuteTask(),否則會跳出,結束整個工作。

不囉嗦上Code!

using System;

namespace DAY27_Chain_of_Responsibility
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 建構子中會帶入下個要執行的Task
            TaskHandler task3 = new Task3(null);
            TaskHandler task2 = new Task2(task3);
            TaskHandler task1 = new Task1(task2);

            task1.ExecuteTask();
        }
    }

    public abstract class TaskHandler
    {
        protected TaskHandler _nextHandler;

        // 建構子帶入下個要做的Task
        public TaskHandler(TaskHandler nextHandler)
        {
            _nextHandler = nextHandler;
        }

        public void ExecuteTask()
        {
            // 先執行各別Task覆寫的HandleTask()
            HandleTask();
            // 如果有下個Task要做則執行下個Task的ExecuteTask()
            if (_nextHandler != null)
            {
                Console.WriteLine($"{this.GetType().Name}完成,將接著執行{_nextHandler.GetType().Name}");
                _nextHandler.ExecuteTask();
            }
            else
            {
                Console.WriteLine("工作結束!");
            }
        }

        public abstract void HandleTask();
    }

    public class Task1 : TaskHandler
    {
        public Task1(TaskHandler handler) : base(handler){}
        public override void HandleTask()
        {
            Console.WriteLine($"Task1處理完畢!");
        }
    }

    public class Task2 : TaskHandler
    {
        public Task2(TaskHandler handler) : base(handler) { }
        public override void HandleTask()
        {
            Console.WriteLine($"Task2處理完畢!");
        }
    }

    public class Task3 : TaskHandler
    {
        public Task3(TaskHandler handler) : base(handler) { }
        public override void HandleTask()
        {
            Console.WriteLine($"Task3處理完畢!");
        }
    }
}
  • 結果

https://ithelp.ithome.com.tw/upload/images/20221002/20136443UsSBg50wUH.png

簡單的小結

今天我們透過 Chain of Responsibility 模式,簡單的說明如何去執行一個排程工作,當一個工作結束後,會再去負責呼叫下一個工作起來運作直到結束,如果大家對於排程這塊有興趣的話,可以去玩玩看 Apache 的「Ariflow」或者是 DotNet 的「Hangfire」,都是不錯的排程工具,那我們就明天繼續囉!


上一篇
【DAY26】Mediator模式 - 瞭解通訊軟體如何去發送訊息
下一篇
【DAY28】Iterator模式 - 無限輪迴的究極奧秘!
系列文
勇闖秘境!探索物件導向背後的設計模式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言